﻿using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace Alimentador.Foods
{
    public class FoodFormulas
    {
        public static string GetIMCClassification(double value)
        {
            value *= 100;

            if (value < (int)DefaultValues.IMCValues.SUBNUTRIDO)
            {
                return MainHelper.GetEnumDescription((Enum)DefaultValues.IMCValues.SUBNUTRIDO);
            }
            else if (value > (int)DefaultValues.IMCValues.SUBNUTRIDO && value <= (int)DefaultValues.IMCValues.PESO_IDEAL)
            {
                return MainHelper.GetEnumDescription((Enum)DefaultValues.IMCValues.PESO_IDEAL);
            }
            else if (value > (int)DefaultValues.IMCValues.PESO_IDEAL && value < (int)DefaultValues.IMCValues.LEVEMENTE_ACIMA_DO_PESO)
            {
                return MainHelper.GetEnumDescription((Enum)DefaultValues.IMCValues.LEVEMENTE_ACIMA_DO_PESO);
            }
            else if (value > (int)DefaultValues.IMCValues.LEVEMENTE_ACIMA_DO_PESO && value <= (int)DefaultValues.IMCValues.PRIMEIRO_GRAU_DE_OBESIDADE)
            {
                return MainHelper.GetEnumDescription((Enum)DefaultValues.IMCValues.PRIMEIRO_GRAU_DE_OBESIDADE);
            }
            else if (value > (int)DefaultValues.IMCValues.PRIMEIRO_GRAU_DE_OBESIDADE && value <= (int)DefaultValues.IMCValues.SEGUNDO_GRAU_DE_OBESIDADE)
            {
                return MainHelper.GetEnumDescription((Enum)DefaultValues.IMCValues.SEGUNDO_GRAU_DE_OBESIDADE);
            }
            else if (value > (int)DefaultValues.IMCValues.SEGUNDO_GRAU_DE_OBESIDADE)
            {
                return MainHelper.GetEnumDescription((Enum)DefaultValues.IMCValues.OBESIDADE_MORBIDA);
            }
         
            return "";
        }

        /// <summary>
        /// Calculate the IMC value for the given weight and height.
        /// </summary>
        /// <param name="patient">PersonPatient</param>
        /// <returns>double</returns>
        public static double CalculateIMC(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            return (patient.PatWeight / (patient.PatHeight * patient.PatHeight)) * 10000;
        }

        /// <summary>
        /// Return a string value according to Person values.
        /// </summary>
        /// <param name="patient">PersonPatient</param>
        /// <returns>string</returns>
        public static DefaultValues.PCValues CalculatePC(PersonPatient patient)
        {
            if (patient == null)
                return DefaultValues.PCValues.None;

            if (patient.PatGender == PersonPatient.Gender.Male)
            {
                if (patient.PatWaist > 0 && patient.PatWaist <= (double)DefaultValues.PCValues.MaleNormal)
                {
                    return DefaultValues.PCValues.MaleNormal;
                }
                else if (patient.PatWaist > (double)DefaultValues.PCValues.MaleNormal && patient.PatWaist <= (double)DefaultValues.PCValues.MaleRisk)
                {
                    return DefaultValues.PCValues.MaleRisk;
                }
                else if (patient.PatWaist >= (double)DefaultValues.PCValues.MaleHighRisk)
                {
                    return DefaultValues.PCValues.MaleHighRisk;
                }
            }
            else
            {
                if (patient.PatWaist > 0 && patient.PatWaist <= (double)DefaultValues.PCValues.FemaleNormal)
                {
                    return DefaultValues.PCValues.FemaleNormal;
                }
                else if (patient.PatWaist > (double)DefaultValues.PCValues.FemaleNormal && patient.PatWaist <= (double)DefaultValues.PCValues.FemaleRisk)
                {
                    return DefaultValues.PCValues.FemaleRisk;
                }
                else if (patient.PatWaist >= (double)DefaultValues.PCValues.FemaleHighRisk)
                {
                    return DefaultValues.PCValues.FemaleHighRisk;
                }
            }

            return DefaultValues.PCValues.None;
        }

        /// <summary>
        /// Calculate Age according to given Year
        /// </summary>
        /// <param name="year">int</param>
        /// <returns>int</returns>
        public static int CalculateAge(int year)
        {
            int val = DateTime.Now.Year - year;
            return (val < 0) ? 0 : val;
        }

        /// <summary>
        /// Calculate Recommended energy based on given values
        /// </summary>
        /// <param name="patient">PersonPatient</param>
        /// <returns></returns>
        public static double RecommendedEnergy(int numDays, PersonPatient patient = null)
        {
            if (patient == null && MainWindow.CurrentPatient != null)
            {
                patient = MainWindow.CurrentPatient;
            }

            if (patient == null)
                return 0;

            double result = 0;

            switch (patient.PatStarRating)
            {
                case DefaultValues.PatStarRatingValues.ActivitySedentary:
                    {
                        result = MainWindow.Def.SEDENTARY_VALUE;
                        break;
                    }
                case DefaultValues.PatStarRatingValues.ActivityModerate:
                    {
                        result = MainWindow.Def.MODERATE_ACTIVE_VALUE;
                        break;
                    }
                case DefaultValues.PatStarRatingValues.ActivityLight:
                    {
                        result = MainWindow.Def.LIGHTLY_ACTIVE_VALUE;
                        break;
                    }
                case DefaultValues.PatStarRatingValues.ActivityHigh:
                    {
                        result = MainWindow.Def.HIGHLY_ACTIVE_VALUE;
                        break;
                    }
                case DefaultValues.PatStarRatingValues.ActivityExtra:
                    {
                        result = MainWindow.Def.EXTREMELY_ACTIVE_VALUE;
                        break;
                    }
                default:
                    {
                        result = 1;
                        break;
                    }
            }

            if (patient.PatGender == PersonPatient.Gender.Male)
            {
                result *= MainWindow.Def.MALE_FACTOR + (MainWindow.Def.MALE_HEIGHT_FACTOR * patient.PatHeight) + (MainWindow.Def.MALE_WEIGHT_FACTOR * patient.PatWeight) - (MainWindow.Def.MALE_AGE_FACTOR * CalculateAge(patient.PatBirthYear));
            }
            else if (patient.PatGender == PersonPatient.Gender.Female)
            {
                result *= MainWindow.Def.FEMALE_FACTOR + (MainWindow.Def.FEMALE_HEIGHT_FACTOR * patient.PatHeight) + (MainWindow.Def.FEMALE_WEIGHT_FACTOR * patient.PatWeight) - (MainWindow.Def.FEMALE_AGE_FACTOR * CalculateAge(patient.PatBirthYear));

                if (patient.PatPregnant == true)
                {
                    result += MainWindow.Def.FEMALE_PREGNANT_FACTOR;
                }
                else if (patient.PatFeeding == true)
                {
                    result += MainWindow.Def.FEMALE_FEEDING_FACTOR;
                }
            }
            return (result < 0) ? 0 : result * numDays;
        }

        /// <summary>
        /// Sum all quantities for a given Property Name and return the result
        /// </summary>
        /// <param name="foodList">List(Food)</param>
        /// <returns>double</returns>
        public static double ObtainedPropertyByFoodList(List<FoodBase> foodList, PropertyName propName)
        {
            double result = 0;
            foreach (Food food in foodList)
            {
                FoodProperty fp = food.PropertyList.Find(f => f.PropertyName == propName);
                FoodProperty pp = food.PropertyList.Find(f => f.PropertyName == PropertyName.Porcao);

                if (fp != null && pp != null)
                    result += fp.Quantity * pp.Quantity * 0.01;
            }
            return (result < 0) ? 0 : result;
        }

        public static double RecommendedWater(int numDays)
        {
            return MainWindow.Def.WATER_FACTOR * numDays;
        }

        public static double RecommendedProtein(int numDays, PersonPatient patient = null)
        {
            if (patient == null && MainWindow.CurrentPatient != null)
                patient = MainWindow.CurrentPatient;

            return (patient == null) ? 0 : (RecommendedEnergy(numDays, patient) * MainWindow.Def.PROTEIN_FACTOR) / MainWindow.Def.PROTEIN_RATIO;
        }

        public static double RecommendedLipids(int numDays, PersonPatient patient = null)
        {
            if (patient == null && MainWindow.CurrentPatient != null)
                patient = MainWindow.CurrentPatient;

            return (patient == null) ? 0 : (RecommendedEnergy(numDays, patient) * MainWindow.Def.LIPIDS_FACTOR) / MainWindow.Def.LIPIDS_RATIO;
        }

        public static double RecommendedCarbonHidrats(int numDays, PersonPatient patient = null)
        {
            if (patient == null && MainWindow.CurrentPatient != null)
                patient = MainWindow.CurrentPatient;

            return (patient == null) ? 0 : (RecommendedEnergy(numDays, patient) * MainWindow.Def.CARBON_HIDRATS_FACTOR) / MainWindow.Def.CARBON_HIDRATS_RATIO;
        }

        public static double RecommendedFiber(int numDays)
        {
            return MainWindow.Def.FIBER_FACTOR * numDays;
        }
        public static double RecommendedColesterol(int numDays)
        {
            return MainWindow.Def.COLESTEROL_FACTOR * numDays;
        }

        public static int RecommendedMonoDissacaridos(int numDays, PersonPatient.Gender gender)
        {
            return ((gender == PersonPatient.Gender.Male) ? MainWindow.Def.MONO_DISSACARIDOS_MALE_FACTOR: MainWindow.Def.MONO_DISSACARIDOS_FEMALE_FACTOR) * numDays;
        }

        public static int RecommendedAcidosGordosSaturados(int numDays, PersonPatient.Gender gender)
        {
            return ((gender == PersonPatient.Gender.Male) ? MainWindow.Def.SATURATED_FAT_SATURATED_ACID_MALE_FACTOR : MainWindow.Def.SATURATED_FAT_ACID_FEMALE_FACTOR) * numDays;
        }

        public static int RecommendedAcidosGordosMonoinsaturados(int numDays, PersonPatient.Gender gender)
        {
            return ((gender == PersonPatient.Gender.Male) ? MainWindow.Def.MONO_INSATURATED_FAT_ACID_MALE_FACTOR : MainWindow.Def.MONO_INSATURATED_FAT_ACID_FEMALE_FACTOR) * numDays;
        }

        public static int RecommendedAcidosGordosPolinsaturados(int numDays, PersonPatient.Gender gender)
        {
            return ((gender == PersonPatient.Gender.Male) ? MainWindow.Def.POLI_INSATURATED_FAT_ACID_MALE_FACTOR : MainWindow.Def.POLI_INSATURATED_FAT_ACID_FEMALE_FACTOR) * numDays;
        }


        //
        //  Graphics calculations
        //

        public static double EnergyGraphic(List<FoodBase> foodList, int numDays = 1, PersonPatient patient = null)
        {
            if (patient == null && MainWindow.CurrentPatient != null)
            {
                patient = MainWindow.CurrentPatient;
            }

            if (patient == null || foodList.Count == 0)
            {
                return 0;
            }

            return ((ObtainedPropertyByFoodList(foodList, PropertyName.Energia) / RecommendedEnergy(numDays, patient)) * 100);
        }

        public static double ProteinGraphic(List<FoodBase> foodList, int numDays = 1, PersonPatient patient = null)
        {
            if (patient == null && MainWindow.CurrentPatient != null)
            {
                patient = MainWindow.CurrentPatient;
            }

            if (patient == null || foodList.Count == 0)
            {
                return 0;
            }

            return ((ObtainedPropertyByFoodList(foodList, PropertyName.Proteina) / RecommendedProtein(numDays, patient)) * 100);
        }

        public static double LipidsGraphic(List<FoodBase> foodList, int numDays = 1, PersonPatient patient = null)
        {
            if (patient == null && MainWindow.CurrentPatient != null)
                patient = MainWindow.CurrentPatient;

            return (patient == null) ? 0 : ((ObtainedPropertyByFoodList(foodList, PropertyName.GorduraTotal) / RecommendedLipids(numDays, patient)) * 100);
        }

        public static double CarbonHidratesGraphic(List<FoodBase> foodList, int numDays = 1, PersonPatient patient = null)
        {
            if (patient == null && MainWindow.CurrentPatient != null)
            {
                patient = MainWindow.CurrentPatient;
            }

            double val = ObtainedPropertyByFoodList(foodList, PropertyName.TotalHidratosCarbono) / RecommendedCarbonHidrats(numDays, patient) * 100;

            return (patient == null) ? 0 : val;
        }

        public static double FiberGraphic(List<FoodBase> foodList, int numDays, PersonPatient patient = null)
        {
            if (patient == null && MainWindow.CurrentPatient != null)
            {
                patient = MainWindow.CurrentPatient;
            }
            return (patient == null) ? 0 : ((ObtainedPropertyByFoodList(foodList, PropertyName.FibraAlimentar) / RecommendedFiber(numDays)) * 100);
        }

        public static double ColesterolGraphic(List<FoodBase> foodList, int numDays, PersonPatient patient = null)
        {
            if (patient == null && MainWindow.CurrentPatient != null)
            {
                patient = MainWindow.CurrentPatient;
            }

            return (patient == null) ? 0 : ((ObtainedPropertyByFoodList(foodList, PropertyName.Colesterol) / RecommendedColesterol(numDays)) * 100);
        }

        //
        // Energy graphics percentage
        //

        private static double EnergyPercentage(List<FoodBase> foodList)
        {
            return ObtainedPropertyByFoodList(foodList, PropertyName.Energia);
        }

        public static double EnergyProteinPercentage(List<FoodBase> foodList)
        {
            double d = EnergyPercentage(foodList);

            if (d > 0)
                return (ObtainedPropertyByFoodList(foodList, PropertyName.Proteina) * 100) / EnergyPercentage(foodList);
            
            return 0;
        }

        public static double EnergyCarbonHidratsPercentage(List<FoodBase> foodList)
        {
            double d = EnergyPercentage(foodList);

            if (d > 0)
                return (ObtainedPropertyByFoodList(foodList, PropertyName.TotalHidratosCarbono) * 100) / EnergyPercentage(foodList);

            return 0;
        }

        public static double EnergyLipidsPercentage(List<FoodBase> foodList, int numDays)
        {
            double d = EnergyPercentage(foodList);

            if (d > 0)
                return (ObtainedPropertyByFoodList(foodList, PropertyName.GorduraTotal) * 100) / EnergyPercentage(foodList);

            return 0;
        }


        //
        // Fat acids graphics percentage
        //

        /*

         Ácidos Gordos + ácidos monoinsaturados + ácidos polinsaturados = Y

        Para o calculo de percentagem:

        Valor de ácidos gordos X 100 / Y =  %

        Valor de ácidos monoinsaturados X 100 / Y =  %

        Valor de ácidos polinsaturados X 100 / Y =  %
         
         */

        private static double FatAcidTotal(List<FoodBase> foodList)
        {
            return ObtainedPropertyByFoodList(foodList, PropertyName.AcidosGordosMonoinsaturados)
                        + ObtainedPropertyByFoodList(foodList, PropertyName.AcidosGordosPolinsaturados)
                        + ObtainedPropertyByFoodList(foodList, PropertyName.AcidosGordosSaturados);
        }

        public static double FatAcidSaturatedPercentage(List<FoodBase> foodList)
        {
            double d = FatAcidTotal(foodList);

            if (d > 0)
                return (ObtainedPropertyByFoodList(foodList, PropertyName.AcidosGordosSaturados) * 100) / FatAcidTotal(foodList);

            return 0;
        }

        public static double FatAcidMonoSaturatedPercentage(List<FoodBase> foodList)
        {
            double d = FatAcidTotal(foodList);

            if (d > 0)
                return (ObtainedPropertyByFoodList(foodList, PropertyName.AcidosGordosMonoinsaturados) * 100) / FatAcidTotal(foodList);

            return 0;
        }

        public static double FatAcidPoliSaturatedPercentage(List<FoodBase> foodList)
        {
            double d = FatAcidTotal(foodList);

            if (d > 0)
                return (ObtainedPropertyByFoodList(foodList, PropertyName.AcidosGordosPolinsaturados) * 100) / FatAcidTotal(foodList);

            return 0;
        }


        /*
         
         Minerals
          
         */

        public static double RecommendedMineralCalcium(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= MainWindow.Def.FOOD_MINIMUM_AGE)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if ((age >= MainWindow.Def.FOOD_MINIMUM_AGE && age <= MainWindow.Def.FOOD_MEDIUM_AGE) || patient.PatFeeding == true || patient.PatPregnant == true)
                    {
                        return MainWindow.Def.CALCIUM_MINIMUM_FACTOR;
                    }
                    else if (age > (MainWindow.Def.FOOD_MEDIUM_AGE + 1))
                    {
                        return MainWindow.Def.CALCIUM_MEDIUM_FACTOR;
                    }
                }
                else
                {
                    if (age >= MainWindow.Def.FOOD_MINIMUM_AGE && age <= MainWindow.Def.FOOD_MAX_AGE)
                    {
                        return MainWindow.Def.CALCIUM_MINIMUM_FACTOR;
                    }

                    return MainWindow.Def.CALCIUM_MEDIUM_FACTOR;
                }
            }

            return 0;
        }

        public static double PercentageMineralCalcium(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedMineralCalcium(patient);
            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.Calcio) * 100 / (RecommendedMineralCalcium(patient) * numDays);

            return 0;
        }

        public static double RecommendedMineralIron(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatFeeding == true)
                    {
                        return MainWindow.Def.IRON_FEEDING_FACTOR;
                    }
                    else if (patient.PatPregnant == true)
                    {
                        return MainWindow.Def.IRON_PREGNANT_FACTOR;
                    }
                    else if (age >= 18 && age <= 50)
                    {
                        return MainWindow.Def.IRON_MALE_MAX_FACTOR;
                    }
                    else if (age > 51)
                    {
                        return MainWindow.Def.IRON_MALE_MINIMUM_FACTOR;
                    }
                }

                return MainWindow.Def.IRON_MALE_MINIMUM_FACTOR;
            }

            return 0;
        }

        public static double PercentageMineralIron(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedMineralIron(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.Ferro) * 100 / (RecommendedMineralIron(patient) * numDays);

            return 0;
        }

        public static double RecommendedMineralMagnesium(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatPregnant == true)
                    {
                        return 350;
                    }
                    else if (patient.PatFeeding == true || (age >= 18 && age <= 30))
                    {
                        return 310;
                    }
                    else if (age >= 31)
                    {
                        return 320;
                    }
                }
                else
                {
                    if (age >= 18 && age <= 30)
                    {
                        return 400;
                    }

                    return 420;
                }
            }

            return 0;
        }

        public static double PercentageMineralMagnesium(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedMineralMagnesium(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.Magnesio) * 100 / (RecommendedMineralMagnesium(patient) * numDays);

            return 0;
        }

        public static double RecommendedMineralSodium(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatPregnant == true || patient.PatFeeding == true || (age >= 18 && age <= 50))
                    {
                        return 1500;
                    }
                    else if (age >= 51 && age <= 70)
                    {
                        return 1300;
                    }
                    else if (age >= 71)
                    {
                        return 1200;
                    }
                }
                else
                {
                    if (age >= 18 && age <= 50)
                    {
                        return 1500;
                    }
                    else if (age >= 51 && age <= 70)
                    {
                        return 1300;
                    }

                    return 1200;
                }
            }

            return 0;
        }

        public static double PercentageMineralSodium(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedMineralSodium(patient);

            if (d > 0 )
                return ObtainedPropertyByFoodList(foodList, PropertyName.Sodio) * 100 / (RecommendedMineralSodium(patient) * numDays);

            return 0;
        }

        public static double RecommendedMineralPotassium(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatFeeding == true)
                {
                    return 5100;
                }

                return 4700;
            }

            return 0;
        }

        public static double PercentageMineralPotassium(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedMineralPotassium(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.Potassio) * 100 / (RecommendedMineralPotassium(patient) * numDays);

            return 0;
        }

        public static double RecommendedMineralPhosphor = 700;

        public static double PercentageMineralPhosphor(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            return ObtainedPropertyByFoodList(foodList, PropertyName.Fosforo) * 100 / (RecommendedMineralPhosphor * numDays);
        }

        public static double RecommendedMineralZinc(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatFeeding == true)
                    {
                        return 12;
                    }
                    else if (patient.PatPregnant == true)
                    {
                        return 11;
                    }
                    return 8;
                }
                else
                {
                    return 11;
                }
            }

            return 0;
        }

        public static double PercentageMineralZinc(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedMineralZinc(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.Zinco) * 100 / (RecommendedMineralZinc(patient) * numDays);

            return 0;
        }


        /*
         
         Vitamins
         
         */

        public static double RecommendedVitaminA(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatFeeding == true)
                    {
                        return 1300;
                    }
                    else if (patient.PatPregnant == true)
                    {
                        return 770;
                    }
                    return 700;
                }
                else
                {
                    return 900;
                }
            }

            return 0;
        }

        public static double PercentageVitaminA(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedVitaminA(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.VitaminaATotal) * 100 / (RecommendedVitaminA(patient) * numDays);

            return 0;
        }

        public static double RecommendedVitaminC(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatFeeding == true)
                    {
                        return 120;
                    }
                    else if (patient.PatPregnant == true)
                    {
                        return 85;
                    }
                    return 75;
                }
                else
                {
                    return 90;
                }
            }

            return 0;
        }

        public static double PercentageVitaminC(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedVitaminC(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.VitaminaC) * 100 / (RecommendedVitaminC(patient) * numDays);

            return 0;
        }

        public static double RecommendedVitaminB6(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatFeeding == true)
                    {
                        return 2;
                    }
                    else if (patient.PatPregnant == true)
                    {
                        return 1.9;
                    }
                    return 1.3;
                }
                else
                {
                    if (age >= 18 && age <= 50)
                    {
                        return 1.3;
                    }
                    return 1.7;
                }
            }

            return 0;
        }

        public static double PercentageVitaminB6(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedVitaminB6(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.VitaminaB6) * 100 / (RecommendedVitaminB6(patient) * numDays);

            return 0;
        }

        public static double RecommendedVitaminB12(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatFeeding == true)
                    {
                        return 2.8;
                    }
                    else if (patient.PatPregnant == true)
                    {
                        return 2.6;
                    }
                }

                return 2.4;
            }

            return 0;
        }

        public static double PercentageVitaminB12(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedVitaminB12(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.VitaminaB12) * 100 / (RecommendedVitaminB12(patient) * numDays);

            return 0;
        }

        public static double RecommendedATocoferol(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatFeeding == true)
                    {
                        return 19;
                    }
                }

                return 15;
            }

            return 0;
        }

        public static double PercentageATocoferol(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedATocoferol(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.ATocoferol) * 100 / (RecommendedATocoferol(patient) * numDays);

            return 0;
        }

        public static double RecommendedFolatos(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatFeeding == true)
                    {
                        return 600;
                    }
                    else if (patient.PatPregnant == true)
                    {
                        return 500;
                    }
                }

                return 400;
            }

            return 0;
        }

        public static double PercentageFolatos(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedFolatos(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.Folatos) * 100 / (RecommendedFolatos(patient) * numDays);

            return 0;
        }

        public static double RecommendedVitaminD(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if ((patient.PatFeeding == true || patient.PatPregnant == true) && age <= 70)
                    {
                        return 15;
                    }

                    return 20;
                }

                if (age >= 71)
                {
                    return 20;
                }

                return 15;
            }

            return 0;
        }

        public static double PercentageVitaminD(List<FoodBase> foodList, PersonPatient patient, int numDays)
        {
            if (patient == null)
                return 0;

            double d = RecommendedFolatos(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.VitaminaD) * 100 / (RecommendedFolatos(patient) * numDays);

            return 0;
        }

        public static double RecommendedTiamina(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatFeeding == true || patient.PatPregnant == true)
                    {
                        return 1.4;
                    }

                    return 1.1;
                }

                return 1.2;
            }

            return 0;
        }

        public static double PercentageTiamina(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedTiamina(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.Tiamina) * 100 / (RecommendedTiamina(patient) * numDays);

            return 0;
        }

        public static double RecommendedRiboflavina(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatPregnant == true)
                    {
                        return 1.6;
                    }
                    else if (patient.PatFeeding == true)
                    {
                        return 1.4;
                    }

                    return 1.1;
                }

                return 1.3;
            }

            return 0;
        }

        public static double PercentageRiboflavina(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedRiboflavina(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.Riboflavina) * 100 / (RecommendedRiboflavina(patient) * numDays);

            return 0;
        }

        public static double RecommendedNiacina(PersonPatient patient)
        {
            if (patient == null)
                return 0;

            int age = CalculateAge(patient.PatBirthYear);

            if (age >= 18)
            {
                if (patient.PatGender == PersonPatient.Gender.Female)
                {
                    if (patient.PatPregnant == true)
                    {
                        return 18;
                    }
                    else if (patient.PatFeeding == true)
                    {
                        return 17;
                    }

                    return 14;
                }

                return 16;
            }

            return 0;
        }

        public static double PercentageNiacina(List<FoodBase> foodList, PersonPatient patient, int numDays = 1)
        {
            if (patient == null)
                return 0;

            double d = RecommendedNiacina(patient);

            if (d > 0)
                return ObtainedPropertyByFoodList(foodList, PropertyName.Niacina) * 100 / (RecommendedNiacina(patient) * numDays);

            return 0;
        }
    }
}
